package com.hanqi.util.shiro;

import com.hanqi.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.codec.Hex;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;

@Slf4j
public class ShiroUtil {
    /**
     * 加密算法
     */
    final static String HASH_ALGORITHM_SHA256 = "SHA-256";
    final static String HASH_ALGORITHM_MD5 = "MD5";
    /**
     * 循环次数
     */
    final static int HASH_ITERATIONS = 1024;

    /**
     * AESKEY
     */
    final static String AESKEY = ",[AjiEWohgew/.?|";

    private static AesCipherService aesCipherService;

    static {
        aesCipherService = new AesCipherService();
        aesCipherService.setKeySize(16); // 设置key长度
    }

    /**
     * 将字符串转换成salt值的ByteSource对象
     *
     * @param salt
     * @return
     */
    public static ByteSource string2ByteSource(String salt) {
        if (salt == null) {
            return null;
        }
        return new Md5Hash(salt);
    }

    /**
     * sha256加密
     *
     * @param password
     * @return
     */
    public static String sha256(String password) {
        return sha256(password, null);
    }

    public static String sha256(String password, String salt) {
        return new SimpleHash(HASH_ALGORITHM_SHA256, password, string2ByteSource(salt), HASH_ITERATIONS).toString();
    }

    /**
     * md5加密
     *
     * @param password
     * @return
     */
    public static String md5(String password) {
        return md5(password, null);
    }

    public static String md5(String password, String salt) {
        return new SimpleHash(HASH_ALGORITHM_MD5, password, string2ByteSource(salt), HASH_ITERATIONS).toString();
    }

    /**
     * base64加密
     *
     * @return
     */
    public static String encode64(String src) {
        return Base64.encodeToString(src.getBytes());
    }

    /**
     * base64解密
     *
     * @return
     */
    public static String decode64(String encrptText) {
        return Base64.decodeToString(encrptText);
    }

    /**
     * AES加密
     *
     * @return
     */
    public static String encodeAes(String src) {
        return encodeAes(src, AESKEY);
    }

    /**
     * AES加密
     *
     * @return
     */
    public static String encodeAes(String src, String aesKey) {
        boolean flag = valid(aesKey);
        if (flag) {
            return aesCipherService.encrypt(src.getBytes(), aesKey.getBytes()).toHex();
        }
        return null;
    }

    /**
     * AES解密
     *
     * @return
     */
    public static String decodeAes(String encrptText) {
        return decodeAes(encrptText, AESKEY);
    }

    /**
     * AES解密
     *
     * @return
     */
    public static String decodeAes(String encrptText, String aesKey) {
        boolean flag = valid(aesKey);
        if (flag) {
            // 解密
            return new String(aesCipherService
                    .decrypt(Hex.decode(encrptText), aesKey.getBytes()).getBytes());
        }
        return null;
    }

    /**
     * 验证aeskey的长度
     *
     * @param aesKey
     * @return
     */
    private static boolean valid(String aesKey) {
        if (aesKey.length() == 16) {
            return true;
        }
        log.error("Key长度不是16位");
        return false;
    }

    /**
     * 当前session
     *
     * @return
     */
    public static Session getSession() {
        return SecurityUtils.getSubject().getSession();
    }

    public static Subject getSubject() {
        return SecurityUtils.getSubject();
    }

    /**
     * 当前登录用户
     *
     * @return
     */
    public static SysUser getUserEntity() {
        return (SysUser) SecurityUtils.getSubject().getPrincipal();
    }

    public static void setSessionAttribute(String key, Object value) {
        getSession().setAttribute(key, value);
    }

    public static Object getSessionAttribute(String key) {
        return getSession().getAttribute(key);
    }

    public static boolean isLogin() {
        return SecurityUtils.getSubject().getPrincipal() != null;
    }

    public static void logout() {
        SecurityUtils.getSubject().logout();
    }
}
